<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      v-loading="formLoading"
    >
      <el-form-item label="佐证" prop="evidenceUrl">
        <el-upload
          :headers="HEADERS"
          :file-list="formData.evidenceUrl"
          class="evidence-upload"
          :action="actionUrl"
          multiple
          list-type="text"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :before-remove="beforeRemove"
          :on-success="handleUploadSuccess"
          :on-progress="handleUploadProgress"
          :before-upload="handleBeforeUpload"
          @update:file-list="(files) => formData.evidenceUrl = files"
        >
          <template #trigger>
            <el-button type="primary">文件上传</el-button>
          </template>
          <template #tip>
            <div class="el-upload__tip text-gray-500">
              文件大小不能超过20MB（VPN模式下尽量低于5MB）
            </div>
          </template>
        </el-upload>
        <!-- ai识别 -->
        <el-upload
          :show-file-list="false"
          :before-upload="beforeAIUpload"
          :http-request="handleAIUpload"
          accept=".pdf,.doc,.docx"
          style="display:inline-block;margin-left:12px;vertical-align:top;"
        >
          <el-button type="success" plain :loading="aiLoading">AI识别填表</el-button>
        </el-upload>
      </el-form-item>
      <el-form-item label="项目名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入项目名称" />
      </el-form-item>
      <el-form-item label="项目类型" prop="type">
        <el-radio-group v-model="formData.type">
          <el-radio
            v-for="dict in getIntDictOptions(DICT_TYPE.PROJECT_TYPE)"
            :key="dict.value"
            :value="dict.value"
          >
            {{ dict.label }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="主办方" prop="organizer">
        <el-select
          v-model="formData.organizer"
          placeholder="请选择主办方"
          filterable
          clearable
          class="!w-240px"
        >
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.PROJECT_ORGANIZER)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="更多主办方" prop="organizerOther">
        <el-input v-model="formData.organizerOther" placeholder="如果上面没有合适的主办方，请输入" />
      </el-form-item>
      <el-form-item label="级别" prop="level">
        <el-radio-group v-model="formData.level">
          <el-radio
            v-for="dict in getIntDictOptions(DICT_TYPE.PROJECT_LEVEL)"
            :key="dict.value"
            :value="dict.value"
          >
            {{ dict.label }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="第一作者(负责人)" prop="author">
        <el-select
          v-model="formData.author"
          filterable
          remote
          reserve-keyword
          placeholder="请输入名字搜索"
          :remote-method="remoteSearch"
          :loading="userLoading"
          @change="handleAuthorChange"
        >
          <el-option
            v-for="item in userOptions"
            :key="item.id"
            :label="getUserDisplayName(item.id)"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="成员和贡献率" prop="memberList">
        <div v-for="(member, index) in formData.memberList" :key="index" class="member-rate-item">
          <el-select
            v-model="member.userId"
            filterable
            remote
            reserve-keyword
            placeholder="请输入名字搜索"
            :remote-method="remoteSearch"
            :loading="userLoading"
            @change="handleMemberChange(index)"
            style="width: 250px; margin-right: 10px;"
          >
            <el-option
              v-for="item in userOptions"
              :key="item.id"
              :label="getUserDisplayName(item.id)"
              :value="item.id"
            />
          </el-select>
          <el-input-number
            v-model="member.rate"
            :min="1"
            :max="100"
            :precision="0"
            style="width: 150px;"
            placeholder="贡献率%"
          />
          <el-button
            type="danger"
            link
            :icon="Delete"
            @click="removeMember(index)"
            v-if="index !== 0"
          />
        </div>
        <el-button
          type="primary"
          link
          :icon="Plus"
          @click="addMember"
          style="margin-top: 10px;"
        >
          添加成员
        </el-button>
      </el-form-item>
      <el-form-item label="立项时间" prop="projectStartTime">
        <el-date-picker
          v-model="formData.projectStartTime"
          type="date"
          value-format="x"
          placeholder="选择立项时间"
        />
      </el-form-item>
      <el-form-item label="结项时间" prop="projectEndTime">
        <el-date-picker
          v-model="formData.projectEndTime"
          type="date"
          value-format="x"
          placeholder="选择结项时间"
        />
      </el-form-item>
      <el-form-item label="状态" prop="status" required>
        <el-radio-group v-model="formData.status">
          <el-radio
            v-for="dict in getIntDictOptions(DICT_TYPE.PROJECT_STATUS)"
            :key="dict.value"
            :value="dict.value"
          >
            {{ dict.label }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
      <el-button @click="(dialogVisible = false)">取 消</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { ProjectsApi, ProjectsVO } from '@/api/digital/projects'
import { getAccessToken } from '@/utils/auth'
import * as UserApi from '@/api/system/user'
import { Delete, Plus } from '@element-plus/icons-vue'
import { ref, onMounted, watch } from 'vue'
import { ElMessageBox } from 'element-plus'
import { useI18n } from 'vue-i18n'
import { useMessage } from '@/hooks/web/useMessage'
import axios from 'axios'

/** 项目 表单 */
defineOptions({ name: 'ProjectsForm' })

// 定义 emit
const emit = defineEmits({
  success: () => true
})

const actionUrl =
  import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
const HEADERS = { Authorization: 'Bearer ' + getAccessToken() }
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const formData = ref({
  id: undefined,
  name: undefined,
  type: undefined,
  organizer: undefined,
  organizerOther: undefined,
  level: undefined,
  author: undefined,
  memberList: [{ userId: undefined, rate: 0 }], // 初始化一个成员（第一作者）
  projectStartTime: undefined,
  projectEndTime: undefined,
  status: undefined,
  evidenceUrl: [],
  remark: undefined,
  reserved1: undefined,
  reserved2: undefined,
  reserved3: undefined,
  reserved4: undefined,
  reserved5: undefined
})
const formRules = ref({
  name: [
    { required: true, message: '项目名称不能为空', trigger: 'change' },
    { max: 100, message: '项目名称不能超过100个字符', trigger: 'change' }
  ],
  type: [{ required: true, message: '项目类型不能为空', trigger: 'change' }],
  level: [{ required: true, message: '级别不能为空', trigger: 'change' }],
  author: [{ required: true, message: '第一作者(负责人)不能为空', trigger: 'change' }],
  status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
  memberList: [
    {
      type: 'array',
      required: true,
      validator: (rule, value, callback) => {
        if (!value || value.length === 0) {
          callback(new Error('成员不能为空'))
          return
        }

        // 检查是否所有必填字段都已填写
        const hasEmptyFields = value.some(
          (item) => item.userId === undefined || item.rate === undefined || item.rate === null
        )
        if (hasEmptyFields) {
          callback(new Error('请填写完整的成员信息和贡献率'))
          return
        }

        // 检查贡献率是否在有效范围内
        const hasInvalidRate = value.some(
          (item) => item.rate < 1 || item.rate > 100
        )
        if (hasInvalidRate) {
          callback(new Error('贡献率必须在1%到100%之间'))
          return
        }

        // 检查是否有重复成员
        const userIds = value.map(item => item.userId).filter(id => id !== undefined)
        const uniqueUserIds = new Set(userIds)
        if (userIds.length !== uniqueUserIds.size) {
          callback(new Error('成员不能重复'))
          return
        }

        // 检查贡献率总和是否为100
        const totalRate = value.reduce((sum, item) => sum + (item.rate || 0), 0)
        if (totalRate !== 100) {
          callback(new Error('贡献率总和必须等于100%'))
          return
        }
        
        callback()
      },
      trigger: 'change'
    }
  ],
  projectStartTime: [{ required: true, message: '立项时间不能为空', trigger: 'blur' }],
  projectEndTime: [
    {
      validator: (rule, value, callback) => {
        const startTime = formData.value.projectStartTime
        if (startTime && value) {
          const start = new Date(startTime)
          const end = new Date(value)
          if (end <= start) {
            callback(new Error('结项时间必须大于立项时间'))
            return
          }
        }
        callback()
      },
      trigger: 'change'
    }
  ],
  evidenceUrl: [{ required: true, message: '佐证不能为空', trigger: 'change' }]
})
const formRef = ref() // 表单 Ref
const userLoading = ref(false)
const userOptions = ref([])
const userMap = ref(new Map())

// 处理第一作者变化
const handleAuthorChange = (value) => {
  if (value) {
    formData.value.memberList[0].userId = value
    formData.value.memberList[0].rate = 100 // 默认设置第一作者贡献率为100
  }
}

// 处理成员变化
const handleMemberChange = (index) => {
  // 如果是第一个成员（第一作者），同步更新author
  if (index === 0) {
    formData.value.author = formData.value.memberList[0].userId
  }
}

// 远程搜索用户
const remoteSearch = async (query: string) => {
  if (query !== '') {
    userLoading.value = true
    try {
      userOptions.value = Array.from(userMap.value.values()).filter(item => 
        item.username.toLowerCase().includes(query.toLowerCase()) ||
        (item.nickname && item.nickname.toLowerCase().includes(query.toLowerCase()))
      )
    } finally {
      userLoading.value = false
    }
  } else {
    // 当搜索词为空时，显示所有用户
    userOptions.value = Array.from(userMap.value.values())
  }
}

// 初始化用户列表
const initUserOptions = async () => {
  try {
    const data = await UserApi.getAllUser()
    userOptions.value = data
    // 更新用户映射
    data.forEach(user => {
      userMap.value.set(user.id, user)
    })
  } catch (error) {
    console.error('获取用户列表失败:', error)
  }
}

// 获取用户显示名称
const getUserDisplayName = (userId) => {
  const user = userMap.value.get(userId)
  if (user) {
    return `${user.username}${user.nickname ? ` (${user.nickname})` : ''}`
  }
  return ''
}

// 将URL转换为文件对象
const convertUrlToFileObject = (url: string) => {
  if (!url) return null
  
  // 从URL中提取文件名
  const fileName = url.split('/').pop() || 'file'
  
  return {
    name: fileName,
    url: url,
    status: 'success',
    uid: Date.now() + '_' + Math.random().toString(36).slice(2)
  }
}

// 打开弹窗
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  
  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      // 确保用户数据已加载
      await initUserOptions()
      
      formData.value = await ProjectsApi.getProjects(id)
      
      // 转换文件URL为文件对象
      if (formData.value.evidenceUrl) {
        if (typeof formData.value.evidenceUrl === 'string') {
          formData.value.evidenceUrl = [convertUrlToFileObject(formData.value.evidenceUrl)]
        } else if (Array.isArray(formData.value.evidenceUrl)) {
          formData.value.evidenceUrl = formData.value.evidenceUrl
            .filter(url => url) // 过滤掉空值
            .map(url => typeof url === 'string' ? convertUrlToFileObject(url) : url)
        }
      } else {
        formData.value.evidenceUrl = []
      }
      
      // 确保作者ID是数字类型
      if (formData.value.author) {
        formData.value.author = Number(formData.value.author)
      }
      
      // 如果有成员数据，转换为memberList格式
      if (formData.value.member && formData.value.rate) {
        const memberIds = formData.value.member.split(',')
        const rates = formData.value.rate.split(',')
        formData.value.memberList = memberIds.map((id, index) => ({
          userId: Number(id),
          rate: Number(rates[index])
        }))
      } else {
        formData.value.memberList = [{ userId: undefined, rate: 0 }]
      }
    } finally {
      formLoading.value = false
    }
  }
}

// 上传进度处理
const handleUploadProgress = (event: any, uploadFile: any) => {
  uploadFile.percentage = Math.round(event.loaded * 100 / event.total)
}

// 上传前处理
const handleBeforeUpload = (file: File) => {
  // 20MB = 20 * 1024 * 1024 bytes
  const maxSize = 20 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过20MB')
    return false
  }
  return true
}

// 上传成功回调
const handleUploadSuccess = (response: any, uploadFile: any) => {
  if (response.code === 0) {
    const url = response.data
    // 直接修改上传文件的 url
    uploadFile.url = url
    uploadFile.status = 'success'
    // 清除表单验证错误
    formRef.value?.clearValidate(['evidenceUrl'])
  } else {
    message.error('上传失败：' + response.msg)
    uploadFile.status = 'error'
  }
}

// 处理移除文件
const handleRemove = (file: any, uploadFiles: any[]) => {
  // 如果没有文件了，重新触发验证
  if (uploadFiles.length === 0) {
    formRef.value?.validateField('evidenceUrl')
  }
  formData.value.evidenceUrl = uploadFiles
}

// 处理预览
const handlePreview = (uploadFile) => {
  if (uploadFile.url) {
    window.open(uploadFile.url)
  }
}

// 移除前确认
const beforeRemove = async (uploadFile: any, uploadFiles: any[]) => {
  // 如果是因为文件大小超限而被拒绝的文件，直接删除不提示
  if (!uploadFile.url && uploadFile.status === 'ready') {
    return true
  }
  // 正常删除时显示确认提示
  return await ElMessageBox.confirm(`确认删除 ${uploadFile.name} 吗?`)
}

// 初始化表单数据
const resetForm = async () => {
  await initUserOptions()
  formData.value = {
    id: undefined,
    name: undefined,
    type: undefined,
    organizer: undefined,
    organizerOther: undefined,
    level: undefined,
    author: undefined,
    memberList: [{ userId: undefined, rate: 0 }],
    projectStartTime: undefined,
    projectEndTime: undefined,
    status: undefined,
    evidenceUrl: [],
    remark: undefined
  }
  formRef.value?.resetFields()
}

// 提交表单
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()

  // 开始提交
  formLoading.value = true
  try {
    const data = { ...formData.value }
    
    // 处理文件列表，只提取URL
    if (Array.isArray(data.evidenceUrl)) {
      data.evidenceUrl = data.evidenceUrl.map(file => file.url || file).filter(Boolean)
    }

    // 处理成员和贡献率数据
    const memberIds = data.memberList.map(m => m.userId).filter(id => id !== undefined)
    const rates = data.memberList.map(m => m.rate).filter(rate => rate !== undefined)
    data.member = memberIds.join(',')
    data.rate = rates.join(',')
    delete data.memberList // 删除原始的 memberList 数据

    // 确保空值也会被提交
    if (data.organizer === undefined || data.organizer === null) {
      data.organizer = ''
    }
    if (data.projectEndTime === undefined || data.projectEndTime === null) {
      data.projectEndTime = ''
    }

    // 提交请求
    if (formType.value === 'create') {
      await ProjectsApi.createProjects(data)
      message.success(t('common.createSuccess'))
    } else {
      await ProjectsApi.updateProjects(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } catch (error) {
    message.error(t('common.saveError'))
  } finally {
    formLoading.value = false
  }
}

const addMember = () => {
  formData.value.memberList.push({ userId: undefined, rate: 0 })
}

const removeMember = (index: number) => {
  formData.value.memberList.splice(index, 1)
}

const aiLoading = ref(false)
const beforeAIUpload = (file: File) => {
  const maxSize = 20 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过20MB')
    return false
  }
  return true
}


const handleAIUpload = async ({ file }) => {
  aiLoading.value = true
  try {
    const formDataUpload = new FormData()
    formDataUpload.append('file', file)
    // 这里的接口路径请根据后端实际调整
    const res = await axios.post('/ai/projects', formDataUpload, {
      headers: { 'Content-Type': 'multipart/form-data', ...HEADERS, 'tenant-id': '1' }
    })
    if (res.data && res.data.code === 0 && res.data.msg) {
      fillFormByAIResult(res.data.msg)
      ElMessage.success('识别成功，表单已自动填充')
    } else {
      ElMessage.error('识别失败：' + (res.data?.msg || '未知错误'))
    }
  } catch (e) {
    ElMessage.error('识别失败')
  } finally {
    aiLoading.value = false
    return false
  }
}

function fillFormByAIResult(result) {
  let dataObj
  try {
    dataObj = typeof result === 'string' ? JSON.parse(result) : result
  } catch {
    ElMessage.error('识别内容解析失败')
    return
  }

  // 处理成员
  let memberArr = []
  try {
    memberArr = JSON.parse(dataObj.member)
    memberArr = memberArr.map(id => Number(id))
  } catch {
    memberArr = String(dataObj.member).replace(/[\[\]\"]/g, '').split(',').map(id => Number(id.trim()))
  }

  // 贡献率
  let rateArr = []
  if (dataObj.rate) {
    rateArr = String(dataObj.rate).split(',').map(r => Number(r.trim()))
  }

  // 成员
  const validMembers = memberArr.filter(id => userOptions.value.some(user => user.id === id));
  const avgRate = validMembers.length > 0 ? Math.floor(100 / validMembers.length) : 0;
  let remain = 100 - avgRate * validMembers.length;
  formData.value.memberList = validMembers.map((id, idx) => ({
    userId: id,
    rate: idx === 0 ? avgRate + remain : avgRate
  }));

  // 第一作者
  if (validMembers.length > 0 && userOptions.value.some(user => user.id === validMembers[0])) {
    formData.value.author = validMembers[0]
  }

  // 其他字段自动赋值
  Object.keys(dataObj).forEach(key => {
    if (['member', 'rate', 'author'].includes(key)) return
    if (key === 'evidenceUrl' && Array.isArray(dataObj[key])) {
      formData.value.evidenceUrl = dataObj[key].map((url, idx) => ({
        name: typeof url === 'string' ? url.split('/').pop() : `file${idx}`,
        url: url,
        status: 'success',
        uid: Date.now() + idx
      }))
    } else if (key === 'projectStartTime' || key === 'projectEndTime') {
      // 处理AI返回的日期格式，转为时间戳
      let val = dataObj[key]
      if (typeof val === 'string' && val) {
        const date = new Date(val.replace(/-/g, '/'))
        if (!isNaN(date.getTime())) {
          formData.value[key] = date.getTime()
        } else {
          formData.value[key] = undefined
        }
      } else if (typeof val === 'number') {
        formData.value[key] = val
      } else {
        formData.value[key] = undefined
      }
    } else if (formData.value.hasOwnProperty(key)) {
      formData.value[key] = dataObj[key]
    }
  })
}

// 组件挂载时初始化用户列表
onMounted(async () => {
  await initUserOptions()
})

// 确保 open 方法被暴露给父组件
defineExpose({
  open
})

</script>
<style lang="scss" scoped>
:deep(.el-form-item--default .el-form-item__label) {
  width: 130px !important;
}

.member-rate-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.member-rate-item .el-button {
  margin-left: 10px;
}

.evidence-upload {
  :deep(.el-upload-list__item) {
    max-width: 100%;
    overflow: hidden;
    
    .el-upload-list__item-name {
      margin-right: 8px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      flex: 1;
    }
    
    .el-upload-list__item-status-label {
      position: static;
      height: auto;
      line-height: inherit;
    }
  }
}
</style>
